//
// Created by ZYZ on 2020/6/12.
//

#include <stdio.h>
#include <stdlib.h>
#include "linear_stack.h"
#include "../../include/type_linear_stack.h"

//构造一个空 S
Status InitStack(SqStack &S) {

    S.base = (SElemType *) malloc(STACK_INIT_SIZE * sizeof(SElemType));

    if (!S.base)
        exit(OVERFLOW);                     //存储分配失败

    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;

    return OK;
}// InitStack


//销毁栈 S，S 不再存在
Status DestroyStack(SqStack &S) {
    free(S.base);       //因为 S.base 是直接用 malloc() 或 realloc() 申请的内存空间，所以可以直接把 S.base 给 free 掉
    S.base = NULL;
    S.top = NULL;
    S.stacksize = 0;
    return OK;
}//DestroyStack


//把 S 置为空栈
Status ClearStack(SqStack &S) {
    S.top = S.base;
    return OK;
}//ClearStack


//若 S 为空栈，则返回 true，否则返回 false
Status StackEmpty(SqStack S) {
    if (S.top == S.base)return OK;
    return ERROR;
}//StackEmpty


//返回S的元素个数，即栈的长度
int StackLength(SqStack S) {
    return S.top - S.base;
}//StackLength


//若栈不空，则用 e 返回 S 的栈顶元素，并返回 OK；否则返回 ERROR
Status GetTop(SqStack S, SElemType &e) {

    if (S.top == S.base)
        return ERROR;

    e = *(S.top - 1);

    return OK;
}// GetTop


//插入元素 e 为新的顶元素
Status Push(SqStack &S, SElemType e) {

    if (S.top - S.base >= S.stacksize) {     //栈满，追加存储空间

        //使用 realloc() 重新分配空间
        S.base = (SElemType *) realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));

        if (!S.base)
            exit(OVERFLOW); //存储分配失败

        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    }

    *S.top++ = e;

    return OK;
}//Push


//若栈不空，则删除 S 的梭顶元素，用 e 返回其值，并返回 0K；否则返回 ERROR
Status Pop(SqStack &S, SElemType &e) {

    if (S.top == S.base)
        return ERROR;

    e = *--S.top;

    return OK;
}// Pop


//对栈遍历 Visit() 函数
Status StackTraverse(SqStack S, Status  (* visit) (SElemType e)) {
    SElemType *p = S.base;
    while (p != S.top)
        visit(*++p);
    printf("\n");
    return OK;
}
